package com.osfw.activiti.controller.process;

import com.github.pagehelper.PageInfo;
import com.osfw.activiti.domain.ProcessNodeInfo;
import com.osfw.activiti.entity.resource.ActReProcdef;
import com.osfw.activiti.enums.resource.ProcdefActionType;
import com.osfw.activiti.service.resource.IActReProcdefService;
import com.osfw.framework.annotation.Log;
import com.osfw.framework.annotation.RepeatSubmit;
import com.osfw.framework.core.controller.BaseController;
import com.osfw.framework.enums.BusinessType;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 流程定义 Controller
 */
@Controller
@RequestMapping("/osfw/activiti/procdef")
public class ProcdefController extends BaseController {
    private String prefix = "osfw/activiti/procdef";

    @Autowired
    private IActReProcdefService procdefService;

    /**
     * 流程配置功能页面
     */
    @RequiresPermissions("activiti:procdef:view")
    @GetMapping()
    public String procdef() {
        return prefix + "/procdef";
    }

    /**
     * 查询流程配置列表
     *
     * @param procdef
     * @return PageInfo
     */
    @RequiresPermissions("activiti:procdef:list")
    @PostMapping("/list")
    @ResponseBody
    public PageInfo list(ActReProcdef procdef) {
        startPage(ActReProcdef.class);
        List<ActReProcdef> list = procdefService.selectProcdefList(procdef, getSysUser());
        return getPageInfo(list);
    }

    /**
     * 简易流程配置新增页面
     */
    @GetMapping("/addSimple")
    public String addSimple() {
        return prefix + "/addSimple";
    }

    /**
     * 简易流程配置新增页面
     */
    @GetMapping("/addMajor")
    public String addMajor() {
        return prefix + "/addMajor";
    }

    /**
     * 简易流程配置新增页面
     */
    @GetMapping("/editSimple/{procdefId}")
    public String editSimple(@PathVariable("procdefId") Long procdefId, ModelMap mmap) {
        mmap.put("procdef", procdefService.getById(procdefId));
        return prefix + "/editSimple";
    }

    /**
     * 简易流程配置新增页面
     */
    @GetMapping("/editMajor/{procdefId}")
    public String editMajor(@PathVariable("procdefId") Long procdefId, ModelMap mmap) {
        mmap.put("procdef", procdefService.getById(procdefId));
        return prefix + "/editMajor";
    }


    /**
     * 流程配置新增
     *
     * @param procdef
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:add")
    @Log(title = "流程配置新增", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public boolean add(@Validated ActReProcdef procdef) {
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 流程配置修改
     *
     * @param procdef
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:edit")
    @Log(title = "流程配置修改", businessType = BusinessType.INSERT)
    @PostMapping("/edit")
    @ResponseBody
    public boolean edit(@Validated ActReProcdef procdef) {
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 流程配置删除
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:remove")
    @Log(title = "流程配置删除", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public boolean remove(String ids, String deleteReason) {
        ActReProcdef procdef = new ActReProcdef();
        procdef.getParams().put("action", ProcdefActionType.DELETE.getAction());
        procdef.getParams().put("ids", ids);
        procdef.setDeleteReason(deleteReason);
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 流程配置分享
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:edit")
    @Log(title = "流程配置分享", businessType = BusinessType.UPDATE)
    @PostMapping("/share")
    @ResponseBody
    public boolean share(String ids, Integer shareState) {
        ActReProcdef procdef = new ActReProcdef();
        procdef.getParams().put("action", ProcdefActionType.SHARE.getAction());
        procdef.getParams().put("ids", ids);
        procdef.setShareState(shareState);
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 流程配置分享
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:edit")
    @Log(title = "流程配置分享", businessType = BusinessType.UPDATE)
    @PostMapping("/cancelShare")
    @ResponseBody
    public boolean cancelShare(String ids) {
        ActReProcdef procdef = new ActReProcdef();
        procdef.getParams().put("action", ProcdefActionType.CANCEL_SHARE.getAction());
        procdef.getParams().put("ids", ids);
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 流程配置停用
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:edit")
    @Log(title = "流程配置停用", businessType = BusinessType.UPDATE)
    @PostMapping("/suspend")
    @ResponseBody
    public boolean suspend(String ids, String deleteReason) {
        ActReProcdef procdef = new ActReProcdef();
        procdef.getParams().put("action", ProcdefActionType.SUSPEND.getAction());
        procdef.getParams().put("ids", ids);
        procdef.setDeleteReason(deleteReason);
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 流程配置激活
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:edit")
    @Log(title = "流程配置激活", businessType = BusinessType.UPDATE)
    @PostMapping("/activate")
    @ResponseBody
    public boolean activate(Long id) {
        ActReProcdef procdef = new ActReProcdef();
        procdef.getParams().put("action", ProcdefActionType.ACTIVATION.getAction());
        procdef.setProcDefId(id);
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 流程配置发布
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:edit")
    @Log(title = "流程配置发布", businessType = BusinessType.UPDATE)
    @PostMapping("/release")
    @ResponseBody
    public boolean RELEASE(Long id) {
        ActReProcdef procdef = new ActReProcdef();
        procdef.getParams().put("action", ProcdefActionType.RELEASE.getAction());
        procdef.setProcDefId(id);
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 流程配置回退
     */
    @RepeatSubmit
    @RequiresPermissions("activiti:procdef:edit")
    @Log(title = "流程配置回退", businessType = BusinessType.UPDATE)
    @PostMapping("/fallback")
    @ResponseBody
    public boolean fallback(Long id, Integer fallbackVersion, String deleteReason) {
        ActReProcdef procdef = new ActReProcdef();
        procdef.getParams().put("action", ProcdefActionType.FALLBACK.getAction());
        procdef.setProcDefId(id);
        procdef.setDeleteReason(deleteReason);
        procdef.setVersion(fallbackVersion);
        return procdefService.saveProcdef(procdef, getSysUser());
    }

    /**
     * 通过流程key查询所有版本的流程配置信息
     */
    @RepeatSubmit
    @GetMapping("/selectProcdefByProcKey")
    @ResponseBody
    public List<ActReProcdef>  selectProcdefByProcKey(String prockey) {
        return procdefService.selectProcdefByProcKey(prockey);
    }

    /**
     * 获取所有最新版本的流程配置数据
     */
    @RepeatSubmit
    @GetMapping("/selectLatestVersionProcdef")
    @ResponseBody
    public List<ActReProcdef> selectLatestVersionProcdef() {
        return procdefService.selectLatestVersionProcdef(getSysUser());
    }

    /**
     * 获取Start节点信息
     */
    @RepeatSubmit
    @GetMapping("/getStartNodeInfo")
    @ResponseBody
    public ProcessNodeInfo getStartNodeInfo(Long procDefId) {
        return procdefService.getStartNodeInfo(procDefId);
    }

    /**
     * 获取流程下一节点
     */
    @RepeatSubmit
    @GetMapping("/getNextNodeInfo")
    @ResponseBody
    public ProcessNodeInfo getNextNodeInfo(Long procDefId, String actKey) {
        return procdefService.getNextNodeInfo(procDefId, actKey);
    }

    /**
     * 获取End节点信息
     */
    @RepeatSubmit
    @GetMapping("/getEndNodeInfo")
    @ResponseBody
    public ProcessNodeInfo getEndNodeInfo(Long procDefId) {
        return procdefService.getEndNodeInfo(procDefId);
    }

}
